import { ApiInfo, ApiRequestType as ApiMethod, ApiStatus } from '@/utils/eolink'
import _ from 'lodash'

export interface CFG {
  readonly API_JS_DOC: string
  readonly API_METHOD_NAME: 'get' | 'delete' | 'put' | 'post'
  readonly API_METHOD: number
  readonly API_NAME: string
  readonly API_STATUS: number
  readonly API_TS_DTO: string
  readonly API_TS_VO: string
  readonly API_URL: string
  readonly IS_FORM_DATA: boolean
  readonly IS_QUERY: boolean

  file_docs: string
  file_imports: string
}

export const fileNs = {
  file_imports: '',
  file_docs: ''
}
export function getFileImports() {
  return fileNs.file_imports ? fileNs.file_imports + '\n' : ''
}
export function getFileDocs() {
  return fileNs.file_docs ? fileNs.file_docs + '\n' : ''
}
function setFileImports(val: string) {
  fileNs.file_imports = val
}
function setFileDocs(val: string) {
  fileNs.file_docs = val
}

/** 当前是否使用ts */
function getIsTs() {
  return new URLSearchParams(location.search.replace(/^\?/, '')).get('lang') == 'ts'
}

export default function runtime(apiInfo: ApiInfo.IApiInfo, fn?: { (cfg: CFG): boolean | string }) {
  if (fn == null) {
    fn = getFn()
  }
  let file_imports = fileNs.file_imports
  let file_docs = fileNs.file_docs
  const API_JS_DOC: string = ApiInfo.genJsDoc(apiInfo)
  const API_METHOD: ApiMethod = apiInfo.baseInfo.apiRequestType
  const API_METHOD_NAME = ApiMethod[API_METHOD].toLowerCase() as any
  const API_NAME = apiInfo.baseInfo.apiName
  const API_STATUS: ApiStatus = apiInfo.baseInfo.apiStatus
  const API_TS_DTO = ApiInfo.genTsDto(apiInfo)
  const API_TS_VO = ApiInfo.genTsVo(apiInfo)
  const API_URL = apiInfo.baseInfo.apiURI
  const IS_QUERY: boolean = !_.isEmpty(apiInfo.urlParam)
  const IS_FORM_DATA = !IS_QUERY && (apiInfo.baseInfo.apiRequestParamType == 0)

  const args = {
    API_JS_DOC,
    API_METHOD_NAME,
    API_METHOD,
    API_NAME,
    API_STATUS,
    API_TS_DTO,
    API_TS_VO,
    API_URL,
    IS_FORM_DATA,
    IS_QUERY,
    file_docs,
    file_imports
  }

  try {
    return fn(args)
  } finally {
    setFileImports(args.file_imports)
    setFileDocs(args.file_docs)
  }

}

/** 默认函数 */
export function def_cfg(args: CFG): boolean | string {
  const {
    API_JS_DOC,
    API_METHOD_NAME,
    API_METHOD,
    API_STATUS,
    // API_TS_DTO,
    // API_TS_VO,
    API_URL,
    IS_FORM_DATA,
    // file_docs,
    // file_imports
  } = args
  var { IS_QUERY } = args

  args.file_imports = 'import axios from "axios"'

  if (API_METHOD_NAME == 'get') {
    // fix: GET 请求只支持 query 传参，客户端(浏览器)限制
    IS_QUERY = true
  }

  // 跳过路径为空的url
  if (['', '/'].includes(API_URL)) {
    return false
  }
  // 跳过设计中 & 废弃状态的接口
  switch (API_STATUS) {
    case ApiStatus.DEPRECATED:
    case ApiStatus.UNDEF:
      return false
  }
  switch (API_METHOD) {
    case ApiMethod.DEL:

      return (
        `${API_JS_DOC}
export const ${getApiName(API_URL, 'delete')} = (params) => axios.delete("${API_URL}", ${IS_QUERY ? '{ params }' : '{ data: params }'})
`
      )
    case ApiMethod.GET:
      return (
        `${API_JS_DOC}
export const ${getApiName(API_URL, API_METHOD_NAME)} = (params) => axios.${API_METHOD_NAME}("${API_URL}", ${IS_QUERY ? '{ params }' : '{ data: params }'})
`
      )
    case ApiMethod.POST:
    case ApiMethod.PUT:
    default:
      return (
        `${API_JS_DOC}
export const ${getApiName(API_URL, API_METHOD_NAME)} = (params) => axios.${IS_FORM_DATA ? _.camelCase([API_METHOD_NAME, 'form'].join()) : API_METHOD_NAME}("${API_URL}", ${IS_QUERY ? '{ params }' : 'params'})
`
      )
  }
  return 'never' as never

  function getApiName(url: string, method: string) {
    const [, ver = ''] = /\bv(\d+)\b/.exec(url) || []
    return _.camelCase(_([method, ...url.split('/').slice(-2)]).reject(f => /^v\d+$/.test(f)).join()).replace(/[-]/gi, '') + (ver == '1' ? '' : ver)
  }
}

/** oa系统使用的api */
export function ws_cfg(args: CFG) {
  const {
    API_JS_DOC,
    API_METHOD_NAME,
    API_METHOD,
    API_STATUS,
    // API_TS_DTO,
    // API_TS_VO,
    API_URL,
    IS_FORM_DATA,
    IS_QUERY,
    // file_docs,
    // file_imports
  } = args
  args.file_imports = `import axios from '@/utils/axios'`

  // 跳过路径为空的url
  if (['', '/'].includes(API_URL)) {
    return false
  }
  // 跳过设计中 & 废弃状态的接口
  switch (API_STATUS) {
    case ApiStatus.DEPRECATED:
    case ApiStatus.UNDEF:
      return false
  }
  switch (API_METHOD) {
    case ApiMethod.DEL:
    case ApiMethod.GET:
      return (
        `${API_JS_DOC}
export const ${getApiName(API_URL, API_METHOD_NAME)} = (params) => axios.${API_METHOD_NAME}("${API_URL}", ${IS_QUERY ? '{ params }' : '{ data: params }'})
`
      )
    case ApiMethod.POST:
    case ApiMethod.PUT:
    default:
      return (
        `${API_JS_DOC}
export const ${getApiName(API_URL, API_METHOD_NAME)} = (params) => axios.${API_METHOD_NAME}("${API_URL}", ${IS_QUERY ? 'null, { params }' : 'params'})
`
      )
  }
  return 'never' as never

  function getApiName(url: string, method: string) {
    return _.camelCase([method, ...url.split('/').slice(-2)].join()).replace(/[-]/gi, '')
  }
}

export const def = getIsTs() ? yc_cfg_ts : def_cfg

/** 云仓配置(typescript) */
export function yc_cfg_ts(args: CFG): boolean | string {
  const {
    // API_JS_DOC,
    API_METHOD_NAME,
    API_NAME,
    API_METHOD,
    API_STATUS,
    API_TS_DTO,
    API_TS_VO,
    API_URL,
    IS_FORM_DATA,
    IS_QUERY,
    // file_docs,
    // file_imports
  } = args
  args.file_imports = _.trim(`
import R from './_util'
`)

  // 跳过路径为空的url
  if (['', '/'].includes(API_URL)) {
    return false
  }
  // 跳过设计中 & 废弃状态的接口
  switch (API_STATUS) {
    case ApiStatus.DEPRECATED:
    case ApiStatus.UNDEF:
      return false
  }
  switch (API_METHOD) {
    case ApiMethod.DEL:
      return (
        `/** ${API_NAME} */
export const ${getApiName(API_URL, API_METHOD_NAME)} = R.${IS_QUERY ? 'delQuery' : 'del'}<${API_TS_VO},${API_TS_DTO}>("${API_URL}")
`
      )
    case ApiMethod.GET:
      return (
        `/** ${API_NAME} */
export const ${getApiName(API_URL, API_METHOD_NAME)} = R.${API_METHOD_NAME}<${API_TS_VO}, ${API_TS_DTO}>("${API_URL}")
`
      )
    case ApiMethod.POST:
    case ApiMethod.PUT:
    default:
      return (
        `/** ${API_NAME} */
export const ${getApiName(API_URL, API_METHOD_NAME)} = R.${IS_FORM_DATA ? _.camelCase([API_METHOD_NAME, 'form'].join()) : API_METHOD_NAME}<${API_TS_VO}, ${API_TS_DTO}>("${API_URL}")
`
      )
  }
  return 'never' as never

  function getApiName(url: string, method: string) {
    const [, ver = ''] = /\bv(\d+)\b/.exec(url) || []
    return _.camelCase(_([method, ...url.split('/').slice(-3)]).reject(f => /^v\d+$/.test(f)).join()).replace(/[-]/gi, '') + (ver == '1' ? '' : ver)
  }
}

/** 获取自定义配置 */
export function getFn(): {
  (cfg: CFG): any
} {
  const txt = localStorage.getItem('PageEolinkCfginputVal')
  if (txt) {
    eval('window.__gen_fn__ =  ' + txt)
    return eval('window.__gen_fn__')
  } else {
    return getIsTs() ? yc_cfg_ts : def_cfg
  }
}
